package org.groupg.practice.guiPractice.tools;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class CalendarWithTasks extends JFrame {
    private LocalDate currentDate;
    private List<Task> tasks;

    public CalendarWithTasks() {
        currentDate = LocalDate.now();
        tasks = new ArrayList<>();
        initializeUI();
        addSampleTasks(); // 添加示例任务
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }

            CalendarWithTasks calendar = new CalendarWithTasks();
            calendar.setVisible(true);
        });
    }

    // 在 initializeUI 方法中添加任务列表
    private void initializeUI() {
        setTitle("日历任务组件");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1200, 700); // 增加宽度以容纳侧边栏
        setLocationRelativeTo(null);

        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setDividerLocation(800);
        splitPane.setResizeWeight(0.7);

        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // 顶部控制面板
        JPanel controlPanel = createControlPanel();
        mainPanel.add(controlPanel, BorderLayout.NORTH);

        // 日历面板
        JPanel calendarPanel = createCalendarPanel();
        mainPanel.add(new JScrollPane(calendarPanel), BorderLayout.CENTER);

        // 任务列表侧边栏
        JPanel taskListPanel = createTaskListPanel();

        splitPane.setLeftComponent(mainPanel);
        splitPane.setRightComponent(taskListPanel);

        add(splitPane);
    }

    // 创建任务列表面板
    private JPanel createTaskListPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        panel.setPreferredSize(new Dimension(300, 0));

        JLabel titleLabel = new JLabel("任务列表", SwingConstants.CENTER);
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 16));
        panel.add(titleLabel, BorderLayout.NORTH);

        // 任务列表
        DefaultListModel<Task> listModel = new DefaultListModel<>();
        for (Task task : tasks) {
            listModel.addElement(task);
        }

        JList<Task> taskList = new JList<>(listModel);
        taskList.setCellRenderer(new TaskListRenderer());
        taskList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        taskList.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    Task selectedTask = taskList.getSelectedValue();
                    if (selectedTask != null) {
                        showTaskEditDialog(selectedTask);
                    }
                }
            }
        });

        JScrollPane scrollPane = new JScrollPane(taskList);
        panel.add(scrollPane, BorderLayout.CENTER);

        // 刷新按钮
        JButton refreshButton = new JButton("刷新任务列表");
        refreshButton.addActionListener(e -> refreshTaskList(listModel));

        panel.add(refreshButton, BorderLayout.SOUTH);

        return panel;
    }

    // 刷新任务列表
    private void refreshTaskList(DefaultListModel<Task> listModel) {
        listModel.clear();
        for (Task task : tasks) {
            listModel.addElement(task);
        }
    }

    // 任务编辑对话框
    private void showTaskEditDialog(Task task) {
        JDialog dialog = new JDialog(this, "编辑任务", true);
        dialog.setSize(400, 300);
        dialog.setLocationRelativeTo(this);

        JPanel panel = new JPanel(new GridLayout(5, 2, 10, 10));
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        JTextField nameField = new JTextField(task.getName());
        JSpinner startSpinner = new JSpinner(new SpinnerDateModel(
                java.sql.Date.valueOf(task.getStartDate()), null, null, java.util.Calendar.DAY_OF_MONTH));
        JSpinner endSpinner = new JSpinner(new SpinnerDateModel(
                java.sql.Date.valueOf(task.getEndDate()), null, null, java.util.Calendar.DAY_OF_MONTH));

        JSpinner.DateEditor startEditor = new JSpinner.DateEditor(startSpinner, "yyyy-MM-dd");
        JSpinner.DateEditor endEditor = new JSpinner.DateEditor(endSpinner, "yyyy-MM-dd");
        startSpinner.setEditor(startEditor);
        endSpinner.setEditor(endEditor);

        panel.add(new JLabel("任务名称:"));
        panel.add(nameField);
        panel.add(new JLabel("开始日期:"));
        panel.add(startSpinner);
        panel.add(new JLabel("结束日期:"));
        panel.add(endSpinner);

        JButton saveButton = new JButton("保存");
        JButton deleteButton = new JButton("删除");
        JButton cancelButton = new JButton("取消");

        saveButton.addActionListener(e -> {
            String name = nameField.getText();
            java.util.Date startDate = (java.util.Date) startSpinner.getValue();
            java.util.Date endDate = (java.util.Date) endSpinner.getValue();

            if (name.isEmpty() || startDate.after(endDate)) {
                JOptionPane.showMessageDialog(dialog, "请输入有效的任务信息");
                return;
            }

            task.name = name;
            task.startDate = LocalDate.ofInstant(startDate.toInstant(), java.time.ZoneId.systemDefault());
            task.endDate = LocalDate.ofInstant(endDate.toInstant(), java.time.ZoneId.systemDefault());

            dialog.dispose();
            repaint();
        });

        deleteButton.addActionListener(e -> {
            int confirm = JOptionPane.showConfirmDialog(dialog,
                    "确定要删除这个任务吗？", "确认删除", JOptionPane.YES_NO_OPTION);
            if (confirm == JOptionPane.YES_OPTION) {
                tasks.remove(task);
                dialog.dispose();
                repaint();
            }
        });

        cancelButton.addActionListener(e -> dialog.dispose());

        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPanel.add(saveButton);
        buttonPanel.add(deleteButton);
        buttonPanel.add(cancelButton);

        dialog.add(panel, BorderLayout.CENTER);
        dialog.add(buttonPanel, BorderLayout.SOUTH);
        dialog.setVisible(true);
    }

    private JPanel createControlPanel() {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));

        JButton prevMonth = new JButton("← 上个月");
        JButton nextMonth = new JButton("下个月 →");
        JButton todayBtn = new JButton("今天");
        JButton addTaskBtn = new JButton("添加任务");

        JLabel monthLabel = new JLabel();
        updateMonthLabel(monthLabel);

        prevMonth.addActionListener(e -> {
            currentDate = currentDate.minusMonths(1);
            updateMonthLabel(monthLabel);
            repaint();
        });

        nextMonth.addActionListener(e -> {
            currentDate = currentDate.plusMonths(1);
            updateMonthLabel(monthLabel);
            repaint();
        });

        todayBtn.addActionListener(e -> {
            currentDate = LocalDate.now();
            updateMonthLabel(monthLabel);
            repaint();
        });

        addTaskBtn.addActionListener(e -> showAddTaskDialog());

        panel.add(prevMonth);
        panel.add(todayBtn);
        panel.add(monthLabel);
        panel.add(nextMonth);
        panel.add(addTaskBtn);

        return panel;
    }

    private void updateMonthLabel(JLabel label) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月");
        label.setText(currentDate.format(formatter));
        label.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
    }

    // 在 createCalendarPanel 方法中替换日期处理逻辑
    private JPanel createCalendarPanel() {
        JPanel panel = new JPanel(new GridLayout(0, 7, 2, 2));
        panel.setBorder(BorderFactory.createLineBorder(Color.GRAY));

        // 添加星期标题
        String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        for (String day : weekDays) {
            JLabel label = new JLabel(day, SwingConstants.CENTER);
            label.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
            label.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
            label.setOpaque(true);
            label.setBackground(new Color(240, 240, 240));
            panel.add(label);
        }

        // 获取当前月的第一天和总天数
        YearMonth yearMonth = YearMonth.from(currentDate);
        LocalDate firstOfMonth = yearMonth.atDay(1);
        int daysInMonth = yearMonth.lengthOfMonth();

        // 计算第一天是星期几（0=周日, 1=周一, ..., 6=周六）
        int firstDayOfWeek = firstOfMonth.getDayOfWeek().getValue() % 7;

        // 添加上个月的空白单元格（如果需要）
        if (firstDayOfWeek > 0) {
            LocalDate prevMonth = currentDate.minusMonths(1);
            YearMonth prevYearMonth = YearMonth.from(prevMonth);
            int daysInPrevMonth = prevYearMonth.lengthOfMonth();

            for (int i = firstDayOfWeek - 1; i >= 0; i--) {
                int day = daysInPrevMonth - i;
                LocalDate cellDate = LocalDate.of(prevMonth.getYear(), prevMonth.getMonth(), day);
                DayPanel dayPanel = new DayPanel(cellDate, getTasksForDate(cellDate), true);
                panel.add(dayPanel);
            }
        }

        // 添加当前月的日期单元格
        for (int day = 1; day <= daysInMonth; day++) {
            LocalDate cellDate = LocalDate.of(currentDate.getYear(), currentDate.getMonth(), day);
            DayPanel dayPanel = new DayPanel(cellDate, getTasksForDate(cellDate), false);
            panel.add(dayPanel);
        }

        // 添加下个月的空白单元格（如果需要）
        int totalCells = firstDayOfWeek + daysInMonth;
        int remainingCells = 42 - totalCells; // 6行 * 7天 = 42个单元格

        if (remainingCells > 0) {
            LocalDate nextMonth = currentDate.plusMonths(1);
            for (int day = 1; day <= remainingCells; day++) {
                LocalDate cellDate = LocalDate.of(nextMonth.getYear(), nextMonth.getMonth(), day);
                DayPanel dayPanel = new DayPanel(cellDate, getTasksForDate(cellDate), true);
                panel.add(dayPanel);
            }
        }

        return panel;
    }

    private List<Task> getTasksForDate(LocalDate date) {
        List<Task> dailyTasks = new ArrayList<>();
        for (Task task : tasks) {
            if (!date.isBefore(task.getStartDate()) && !date.isAfter(task.getEndDate())) {
                dailyTasks.add(task);
            }
        }
        return dailyTasks;
    }

    private void addSampleTasks() {
        // 添加一些示例任务
        tasks.add(new Task("项目开发", LocalDate.of(2025, 9, 1),
                LocalDate.of(2025, 9, 5), Color.BLUE));
        tasks.add(new Task("会议准备", LocalDate.of(2025, 9, 3),
                LocalDate.of(2025, 9, 7), Color.GREEN));
        tasks.add(new Task("代码审查", LocalDate.of(2025, 9, 8),
                LocalDate.of(2025, 9, 10), Color.ORANGE));
        tasks.add(new Task("测试阶段", LocalDate.of(2025, 9, 12),
                LocalDate.of(2025, 9, 15), Color.RED));
    }

    private void showAddTaskDialog() {
        JDialog dialog = new JDialog(this, "添加新任务", true);
        dialog.setSize(400, 300);
        dialog.setLocationRelativeTo(this);

        JPanel panel = new JPanel(new GridLayout(5, 2, 10, 10));
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        JTextField nameField = new JTextField();
        JSpinner startSpinner = new JSpinner(new SpinnerDateModel());
        JSpinner endSpinner = new JSpinner(new SpinnerDateModel());
        JComboBox<String> colorCombo = new JComboBox<>(new String[]{
                "蓝色", "绿色", "橙色", "红色", "紫色"
        });

        JSpinner.DateEditor startEditor = new JSpinner.DateEditor(startSpinner, "yyyy-MM-dd");
        JSpinner.DateEditor endEditor = new JSpinner.DateEditor(endSpinner, "yyyy-MM-dd");
        startSpinner.setEditor(startEditor);
        endSpinner.setEditor(endEditor);

        panel.add(new JLabel("任务名称:"));
        panel.add(nameField);
        panel.add(new JLabel("开始日期:"));
        panel.add(startSpinner);
        panel.add(new JLabel("结束日期:"));
        panel.add(endSpinner);
        panel.add(new JLabel("任务颜色:"));
        panel.add(colorCombo);

        JButton addButton = new JButton("添加");
        JButton cancelButton = new JButton("取消");

        addButton.addActionListener(e -> {
            String name = nameField.getText();
            java.util.Date startDate = (java.util.Date) startSpinner.getValue();
            java.util.Date endDate = (java.util.Date) endSpinner.getValue();

            if (name.isEmpty() || startDate.after(endDate)) {
                JOptionPane.showMessageDialog(dialog, "请输入有效的任务信息");
                return;
            }

            Color color = switch (colorCombo.getSelectedIndex()) {
                case 0 -> Color.BLUE;
                case 1 -> Color.GREEN;
                case 2 -> Color.ORANGE;
                case 3 -> Color.RED;
                case 4 -> new Color(128, 0, 128); // 紫色
                default -> Color.GRAY;
            };

            tasks.add(new Task(name,
                    LocalDate.ofInstant(startDate.toInstant(), java.time.ZoneId.systemDefault()),
                    LocalDate.ofInstant(endDate.toInstant(), java.time.ZoneId.systemDefault()),
                    color));

            dialog.dispose();
            repaint();
        });

        cancelButton.addActionListener(e -> dialog.dispose());

        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPanel.add(addButton);
        buttonPanel.add(cancelButton);

        dialog.add(panel, BorderLayout.CENTER);
        dialog.add(buttonPanel, BorderLayout.SOUTH);
        dialog.setVisible(true);
    }

    // 任务类
    static class Task {
        public String name; // 改为 public 以便编辑
        private LocalDate startDate;
        private LocalDate endDate;
        private Color color;

        public Task(String name, LocalDate startDate, LocalDate endDate, Color color) {
            this.name = name;
            this.startDate = startDate;
            this.endDate = endDate;
            this.color = color;
        }

        public String getName() {
            return name;
        }

        public LocalDate getStartDate() {
            return startDate;
        }

        public void setStartDate(LocalDate startDate) {
            this.startDate = startDate;
        }

        public LocalDate getEndDate() {
            return endDate;
        }

        public void setEndDate(LocalDate endDate) {
            this.endDate = endDate;
        }

        public Color getColor() {
            return color;
        }

        @Override
        public String toString() {
            return name + " (" + startDate + " - " + endDate + ")";
        }
    }

    // 任务列表渲染器
    class TaskListRenderer extends JPanel implements ListCellRenderer<Task> {
        private JLabel nameLabel;
        private JLabel dateLabel;

        public TaskListRenderer() {
            setLayout(new BorderLayout());
            setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

            nameLabel = new JLabel();
            nameLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));

            dateLabel = new JLabel();
            dateLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 10));
            dateLabel.setForeground(Color.GRAY);

            add(nameLabel, BorderLayout.NORTH);
            add(dateLabel, BorderLayout.SOUTH);
        }

        @Override
        public Component getListCellRendererComponent(JList<? extends Task> list, Task task,
                                                      int index, boolean isSelected, boolean cellHasFocus) {
            nameLabel.setText(task.getName());
            dateLabel.setText(task.getStartDate() + " - " + task.getEndDate());

            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }

            // 设置左侧颜色指示条
            setBorder(BorderFactory.createCompoundBorder(
                    BorderFactory.createEmptyBorder(2, 10, 2, 2),
                    BorderFactory.createMatteBorder(0, 5, 0, 0, task.getColor())
            ));

            return this;
        }
    }

    // 修改 DayPanel 类
    class DayPanel extends JPanel {
        private LocalDate date;
        private List<Task> dailyTasks;
        private boolean isOtherMonth;

        public DayPanel(LocalDate date, List<Task> dailyTasks, boolean isOtherMonth) {
            this.date = date;
            this.dailyTasks = dailyTasks;
            this.isOtherMonth = isOtherMonth;
            setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
            setLayout(new BorderLayout());

            // 日期标签
            JLabel dateLabel = new JLabel(String.valueOf(date.getDayOfMonth()), SwingConstants.CENTER);
            dateLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));

            // 设置不同月份的显示样式
            if (isOtherMonth) {
                dateLabel.setForeground(Color.GRAY);
                setBackground(new Color(245, 245, 245));
            } else if (date.equals(LocalDate.now())) {
                setBackground(new Color(255, 240, 240));
                dateLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
            } else {
                setBackground(Color.WHITE);
            }

            add(dateLabel, BorderLayout.NORTH);

            // 添加鼠标监听器显示任务详情
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2 && !dailyTasks.isEmpty()) {
                        showTaskDetails();
                    }
                }
            });
        }

        private void showTaskDetails() {
            StringBuilder details = new StringBuilder();
            details.append(date.toString()).append("的任务:\n\n");

            for (Task task : dailyTasks) {
                details.append("• ").append(task.getName())
                        .append(" (").append(task.getStartDate())
                        .append(" - ").append(task.getEndDate()).append(")\n");
            }

            JOptionPane.showMessageDialog(this, details.toString(),
                    "任务详情", JOptionPane.INFORMATION_MESSAGE);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            if (!dailyTasks.isEmpty() && !isOtherMonth) {
                Graphics2D g2d = (Graphics2D) g;
                int height = getHeight() - 30;
                int taskHeight = Math.max(15, Math.min(25, height / dailyTasks.size()));

                for (int i = 0; i < dailyTasks.size(); i++) {
                    Task task = dailyTasks.get(i);
                    int y = 30 + i * taskHeight;

                    // 绘制任务条
                    g2d.setColor(task.getColor());
                    g2d.fillRect(5, y, getWidth() - 10, taskHeight - 2);

                    // 绘制任务名称
                    g2d.setColor(Color.WHITE);
                    g2d.setFont(new Font("Microsoft YaHei", Font.PLAIN, 9));

                    String displayName = task.getName();
                    if (displayName.length() > 10) {
                        displayName = displayName.substring(0, 10) + "...";
                    }

                    FontMetrics fm = g2d.getFontMetrics();
                    int textWidth = fm.stringWidth(displayName);

                    if (textWidth < getWidth() - 15) {
                        g2d.drawString(displayName, (getWidth() - textWidth) / 2, y + taskHeight / 2 + 4);
                    } else {
                        // 如果文字太长，只显示前几个字符
                        String shortName = displayName.substring(0, Math.min(5, displayName.length())) + "..";
                        int shortWidth = fm.stringWidth(shortName);
                        g2d.drawString(shortName, (getWidth() - shortWidth) / 2, y + taskHeight / 2 + 4);
                    }
                }
            }
        }
    }
}
